package com.aaaa.scheduler.scheduler.genetic;

import com.aaaa.scheduler.objective.*;
import com.aaaa.scheduler.util.InstanceUtil;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * 配置参数，算法中用到的参数
 */

public class GeneticConfiguration {

    //经典遗传算法的参数
    /**
     * population size    种群大小
     */
    public static int POPULATION_SIZE = 200;
    /**
     * iterator for 200 time for each loop     遗传算法最大的进化迭代次数
     */
    public static int MAX_GENERATIONS = 200;
    /**
     * max iterator no improve      进化后没有提升的最大代数  没有提升的代数超过这个值，就代表陷入局部最优
     */
    public static int MAX_NO_IMPROVE = 30;
    /**
     * Reproduction probability  繁殖概率
     */
    public static double REPRODUCTION_PROBABILITY = 0.10;
    /**
     * Crossover probability   交叉概率
     */
    public static double CROSSOVER_PROBABILITY = 0.80;
    /**
     * Mutation probability    变异概率
     */
    public static double MUTATION_PROBABILITY = 0.10;
    /**
     * perturbation probability    扰动概率  划分种群  三七分
     */
    public static double PRETURBATION_PROBABILITY = 0.30;


    //NSGA-2的参数
    /**
     * NSGA2算法的目标：一般为两个目标
     */
    public static List<Objective> objectiveList = null;
    /**
     * 画帕累托前沿 的 双目标坐标系：x坐标的title - 其中一个目标
     */
    public static String X_AXIS_TITLE;
    /**
     * 画帕累托前沿 的 双目标坐标系：y坐标的title - 另一个目标
     */
    public static String Y_AXIS_TITLE;


    /**
     * 三目标坐标系：z坐标的title - 另一个目标
     */
    public static String Z_AXIS_TITLE;

    /**
     * 四目标坐标系：w坐标的title - 另一个目标
     */
    public static String W_AXIS_TITLE;

    /**
     * 五目标坐标系：v坐标的title - 另一个目标
     */
    public static String V_AXIS_TITLE;

    /**
     * 使用的目标数
     */
    public static int objectiveNum = 3;


//    private final int maxT = 9;// tabu list length
//    private final int maxTabuLimit = 100;// maxTSIterSize = maxTabuLimit * (Gen / MAX_GENERATIONS)
//    private final double pt = 0.05;// tabu probability
//
//    private final int timeLimit = -1;// no time limit


    /**
     * 功能描述：配置类初始化
     *
     */
    public static void configure() {
        //初始化目标
        GeneticConfiguration.objectiveList = buildObjectives();

        InstanceUtil.reportAlgorithmStart();

        GeneticConfiguration.setAxisTitles();

        InstanceUtil.reportDefaultConfiguration();
    }

    /**
     * 功能描述：初始化两个目标
     *
     */
    public static List<Objective> buildObjectives() {
        List<Objective> newObjectives = new ArrayList<>();

        newObjectives.add(0, new ObjectiveCmax());
        if(GeneticConfiguration.objectiveNum > 1)
            newObjectives.add(1, new ObjectiveLoadMax());
        if(GeneticConfiguration.objectiveNum > 2)
            newObjectives.add(2, new ObjectiveLoadSum());
        if(GeneticConfiguration.objectiveNum > 3)
            newObjectives.add(3, new ObjectiveUtilityAvg());

        return newObjectives;

    }

    /**
     * 功能描述：将目标名设置成坐标名
     *
     */
    private static void setAxisTitles() {
        GeneticConfiguration.X_AXIS_TITLE = GeneticConfiguration.objectiveList.get(0).getObjectiveName();
        if(GeneticConfiguration.objectiveNum > 1)
            GeneticConfiguration.Y_AXIS_TITLE = GeneticConfiguration.objectiveList.get(1).getObjectiveName();
        if(GeneticConfiguration.objectiveNum > 2)
            GeneticConfiguration.Z_AXIS_TITLE = GeneticConfiguration.objectiveList.get(2).getObjectiveName();
        if(GeneticConfiguration.objectiveNum > 3)
            GeneticConfiguration.W_AXIS_TITLE = GeneticConfiguration.objectiveList.get(3).getObjectiveName();

    }

    /**
     * 功能描述：自定义种群大小 和 遗传迭代次数
     *
     */
    private static void setCustomConfiguration(final BufferedReader bufferedReader) throws IOException {

        System.out.print("输入染色体大小: ");
        GeneticConfiguration.POPULATION_SIZE = Integer.parseInt(bufferedReader.readLine());

        System.out.print("输入遗传的最大代数: ");
        GeneticConfiguration.MAX_GENERATIONS = Integer.parseInt(bufferedReader.readLine());

        System.out.print("输入交叉率: ");
        GeneticConfiguration.CROSSOVER_PROBABILITY = Integer.parseInt(bufferedReader.readLine());

        System.out.print("输入变异率: ");
        GeneticConfiguration.MUTATION_PROBABILITY = Integer.parseInt(bufferedReader.readLine());
    }

    /**
     * 功能描述：自定义两个目标 x、y坐标
     *
     */
    private static void setCustomAxisTitles(final BufferedReader bufferedReader) throws IOException {

        System.out.print("\n是否提供自定义的坐标（目标） (y/n): ");

        switch(bufferedReader.readLine()) {

            case "y":

                System.out.print("\n输入X坐标名: ");
                GeneticConfiguration.X_AXIS_TITLE = bufferedReader.readLine();

                System.out.print("输入Y坐标名: ");
                GeneticConfiguration.Y_AXIS_TITLE = bufferedReader.readLine();

                break;
            case "n": break;
            default: InstanceUtil.reportWrongInput(); break;
        }
    }

}
